{% extends "base.html" %}

{% block title %}调用日志 - MinerU 文档解析系统{% endblock %}

{% block page_title %}调用日志{% endblock %}

{% block content %}
<div class="fade-in">
    <!-- 筛选和搜索 -->
    <div class="bg-white rounded-xl shadow-sm p-6 mb-6">
        <div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
            <div class="flex flex-col md:flex-row gap-4">
                <input type="date" id="startDate" class="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
                <input type="date" id="endDate" class="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
                
                <select id="methodFilter" class="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
                    <option value="">所有方法</option>
                    <option value="GET">GET</option>
                    <option value="POST">POST</option>
                    <option value="PUT">PUT</option>
                    <option value="DELETE">DELETE</option>
                </select>
                
                <select id="statusFilter" class="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
                    <option value="">所有状态</option>
                    <option value="200">成功 (200)</option>
                    <option value="400">客户端错误 (400)</option>
                    <option value="401">未授权 (401)</option>
                    <option value="403">禁止访问 (403)</option>
                    <option value="404">未找到 (404)</option>
                    <option value="500">服务器错误 (500)</option>
                </select>
                
                <input type="text" id="searchInput" placeholder="搜索路径或用户..." 
                       class="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
            </div>
            
            <div class="flex items-center space-x-2">
                <button id="searchBtn" class="btn-primary text-white px-4 py-2 rounded-md hover:bg-blue-700">
                    <i class="fas fa-search mr-2"></i>搜索
                </button>
                <button id="refreshBtn" class="text-blue-600 hover:text-blue-800">
                    <i class="fas fa-sync-alt"></i>
                </button>
                <button id="exportBtn" class="text-green-600 hover:text-green-800">
                    <i class="fas fa-download"></i>
                </button>
            </div>
        </div>
    </div>
    
    <!-- 日志统计 -->
    <div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-6">
        <div class="bg-white rounded-xl shadow-sm p-6 hover-scale">
            <div class="flex items-center justify-between">
                <div>
                    <p class="text-sm text-gray-500 mb-1">总调用次数</p>
                    <p class="text-2xl font-bold text-gray-800" id="totalRequests">0</p>
                </div>
                <div class="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center">
                    <i class="fas fa-chart-line text-blue-600 text-xl"></i>
                </div>
            </div>
        </div>
        
        <div class="bg-white rounded-xl shadow-sm p-6 hover-scale">
            <div class="flex items-center justify-between">
                <div>
                    <p class="text-sm text-gray-500 mb-1">成功率</p>
                    <p class="text-2xl font-bold text-gray-800" id="successRate">0%</p>
                </div>
                <div class="w-12 h-12 bg-green-100 rounded-lg flex items-center justify-center">
                    <i class="fas fa-check-circle text-green-600 text-xl"></i>
                </div>
            </div>
        </div>
        
        <div class="bg-white rounded-xl shadow-sm p-6 hover-scale">
            <div class="flex items-center justify-between">
                <div>
                    <p class="text-sm text-gray-500 mb-1">平均响应时间</p>
                    <p class="text-2xl font-bold text-gray-800" id="avgResponseTime">0ms</p>
                </div>
                <div class="w-12 h-12 bg-orange-100 rounded-lg flex items-center justify-center">
                    <i class="fas fa-clock text-orange-600 text-xl"></i>
                </div>
            </div>
        </div>
        
        <div class="bg-white rounded-xl shadow-sm p-6 hover-scale">
            <div class="flex items-center justify-between">
                <div>
                    <p class="text-sm text-gray-500 mb-1">错误次数</p>
                    <p class="text-2xl font-bold text-gray-800" id="errorCount">0</p>
                </div>
                <div class="w-12 h-12 bg-red-100 rounded-lg flex items-center justify-center">
                    <i class="fas fa-exclamation-triangle text-red-600 text-xl"></i>
                </div>
            </div>
        </div>
    </div>
    
    <!-- 日志列表 -->
    <div class="bg-white rounded-xl shadow-sm overflow-hidden">
        <div class="px-6 py-4 border-b border-gray-200">
            <div class="flex items-center justify-between">
                <h3 class="text-lg font-semibold text-gray-800">调用日志</h3>
                <div class="flex items-center space-x-4">
                    <label class="flex items-center">
                        <input type="checkbox" id="autoRefresh" class="mr-2">
                        <span class="text-sm text-gray-600">自动刷新</span>
                    </label>
                    <select id="pageSize" class="px-3 py-1 border border-gray-300 rounded-md text-sm">
                        <option value="20">20条/页</option>
                        <option value="50">50条/页</option>
                        <option value="100">100条/页</option>
                    </select>
                </div>
            </div>
        </div>
        
        <div class="overflow-x-auto">
            <table class="w-full">
                <thead class="bg-gray-50">
                    <tr>
                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">时间</th>
                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">方法</th>
                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">路径</th>
                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">状态</th>
                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">响应时间</th>
                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">用户</th>
                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">IP</th>
                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">操作</th>
                    </tr>
                </thead>
                <tbody id="logsTableBody" class="bg-white divide-y divide-gray-200">
                    <tr>
                        <td colspan="8" class="px-6 py-12 text-center text-gray-500">
                            <i class="fas fa-spinner fa-spin text-2xl mb-2"></i>
                            <p>加载中...</p>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>
        
        <!-- 分页 -->
        <div class="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6">
            <div class="flex-1 flex justify-between sm:hidden">
                <button id="prevPageMobile" class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
                    上一页
                </button>
                <button id="nextPageMobile" class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
                    下一页
                </button>
            </div>
            <div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
                <div>
                    <p class="text-sm text-gray-700">
                        显示 <span id="startItem" class="font-medium">1</span> 到 <span id="endItem" class="font-medium">20</span> 条，
                        共 <span id="totalItems" class="font-medium">0</span> 条记录
                    </p>
                </div>
                <div>
                    <nav class="relative z-0 inline-flex rounded-md shadow-sm -space-x-px" id="pagination">
                        <!-- 分页按钮将通过JavaScript动态生成 -->
                    </nav>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- 日志详情模态框 -->
<div id="logModal" class="modal fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full hidden">
    <div class="relative top-20 mx-auto p-5 border w-11/12 max-w-4xl shadow-lg rounded-md bg-white">
        <div class="mt-3">
            <div class="flex items-center justify-between mb-4">
                <h3 class="text-lg font-semibold text-gray-800">日志详情</h3>
                <button onclick="closeLogModal()" class="text-gray-400 hover:text-gray-600">
                    <i class="fas fa-times"></i>
                </button>
            </div>
            
            <div id="logDetails" class="space-y-4">
                <!-- 日志详情将通过JavaScript动态生成 -->
            </div>
        </div>
    </div>
</div>
{% endblock %}

{% block extra_js %}
<script>
let currentPage = 1;
let pageSize = 20;
let totalLogs = 0;
let autoRefreshInterval = null;

// 页面加载时初始化
document.addEventListener('DOMContentLoaded', function() {
    loadLogs();
    loadLogStats();
    setupEventListeners();
    setDefaultDates();
});

// 设置默认日期
function setDefaultDates() {
    const today = new Date();
    const weekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);
    
    document.getElementById('endDate').value = today.toISOString().split('T')[0];
    document.getElementById('startDate').value = weekAgo.toISOString().split('T')[0];
}

// 设置事件监听器
function setupEventListeners() {
    document.getElementById('searchBtn').addEventListener('click', () => {
        currentPage = 1;
        loadLogs();
        loadLogStats();
    });
    
    document.getElementById('refreshBtn').addEventListener('click', () => {
        loadLogs();
        loadLogStats();
    });
    
    document.getElementById('exportBtn').addEventListener('click', exportLogs);
    document.getElementById('pageSize').addEventListener('change', (e) => {
        pageSize = parseInt(e.target.value);
        currentPage = 1;
        loadLogs();
    });
    
    document.getElementById('autoRefresh').addEventListener('change', (e) => {
        if (e.target.checked) {
            autoRefreshInterval = setInterval(() => {
                loadLogs();
                loadLogStats();
            }, 5000);
        } else {
            clearInterval(autoRefreshInterval);
        }
    });
    
    // Enter键搜索
    document.getElementById('searchInput').addEventListener('keypress', (e) => {
        if (e.key === 'Enter') {
            document.getElementById('searchBtn').click();
        }
    });
}

// 加载日志列表
async function loadLogs() {
    try {
        const startDate = document.getElementById('startDate').value;
        const endDate = document.getElementById('endDate').value;
        const method = document.getElementById('methodFilter').value;
        const status = document.getElementById('statusFilter').value;
        const search = document.getElementById('searchInput').value;
        
        const params = new URLSearchParams();
        params.append('page', currentPage);
        params.append('page_size', pageSize);
        if (startDate) params.append('start_date', startDate);
        if (endDate) params.append('end_date', endDate);
        if (method) params.append('method', method);
        if (status) params.append('status_code', status);
        if (search) params.append('endpoint', search);
        
        let url = `/api/v1/admin/logs?${params.toString()}`;
        
        const response = await apiRequest(url);
        
        // 更新日志列表
        updateLogsTable(response.items || []);
        
        // 更新分页
        totalLogs = response.total || 0;
        updatePagination();
        
    } catch (error) {
        console.error('加载日志失败:', error);
        // 如果是认证错误，尝试重新登录
        if (error.message.includes('401') || error.message.includes('未授权') || error.message.includes('Unauthorized')) {
            // 清除过期的token
            localStorage.removeItem('auth_token');
            // 显示重新登录提示
            document.getElementById('logsTableBody').innerHTML = `
                <tr>
                    <td colspan="8" class="px-6 py-12 text-center text-gray-500">
                        <i class="fas fa-exclamation-triangle text-2xl mb-2"></i>
                        <p>登录已过期，请重新登录</p>
                        <button onclick="window.location.href='/web/login'" class="mt-2 btn-primary text-white px-4 py-2 rounded-md hover:bg-blue-700">
                            重新登录
                        </button>
                    </td>
                </tr>
            `;
        } else {
            // 其他错误显示通用错误信息
            document.getElementById('logsTableBody').innerHTML = `
                <tr>
                    <td colspan="8" class="px-6 py-12 text-center text-gray-500">
                        <i class="fas fa-exclamation-triangle text-2xl mb-2"></i>
                        <p>加载失败: ${error.message}</p>
                        <button onclick="loadLogs()" class="mt-2 btn-primary text-white px-4 py-2 rounded-md hover:bg-blue-700">
                            重试
                        </button>
                    </td>
                </tr>
            `;
        }
    }
}

// 加载日志统计
async function loadLogStats() {
    try {
        const startDate = document.getElementById('startDate').value;
        const endDate = document.getElementById('endDate').value;
        const method = document.getElementById('methodFilter').value;
        const status = document.getElementById('statusFilter').value;
        const search = document.getElementById('searchInput').value;
        
        const params = new URLSearchParams();
        if (startDate) params.append('start_date', startDate);
        if (endDate) params.append('end_date', endDate);
        if (method) params.append('method', method);
        if (status) params.append('status_code', status);
        if (search) params.append('endpoint', search);
        
        let url = '/api/v1/admin/logs/stats';
        if (params.toString()) url += '?' + params.toString();
        
        const response = await apiRequest(url);
        
        document.getElementById('totalRequests').textContent = response.total_requests || 0;
        document.getElementById('successRate').textContent = (response.success_rate || 0).toFixed(1) + '%';
        document.getElementById('avgResponseTime').textContent = ((response.avg_response_time || 0) * 1000).toFixed(0) + 'ms';
        document.getElementById('errorCount').textContent = response.error_count || 0;
        
    } catch (error) {
        console.error('加载日志统计失败:', error);
        // 如果是认证错误，尝试重新登录
        if (error.message.includes('401') || error.message.includes('未授权') || error.message.includes('Unauthorized')) {
            // 清除过期的token
            localStorage.removeItem('auth_token');
            // 显示重新登录提示
            document.getElementById('totalRequests').textContent = '--';
            document.getElementById('successRate').textContent = '--';
            document.getElementById('avgResponseTime').textContent = '--';
            document.getElementById('errorCount').textContent = '--';
            
            // 显示错误提示
            const statsContainer = document.querySelector('.grid.grid-cols-1.md\:grid-cols-4.gap-4');
            if (statsContainer) {
                statsContainer.innerHTML += `
                    <div class="col-span-full bg-red-50 border border-red-200 rounded-lg p-4 mt-4">
                        <div class="flex items-center">
                            <i class="fas fa-exclamation-triangle text-red-500 mr-2"></i>
                            <p class="text-red-700">登录已过期，请<a href="/web/login" class="underline">重新登录</a></p>
                        </div>
                    </div>
                `;
            }
        } else {
            // 其他错误显示默认值
            document.getElementById('totalRequests').textContent = '--';
            document.getElementById('successRate').textContent = '--';
            document.getElementById('avgResponseTime').textContent = '--';
            document.getElementById('errorCount').textContent = '--';
        }
    }
}

// 更新日志表格
function updateLogsTable(logs) {
    const tbody = document.getElementById('logsTableBody');
    
    if (logs.length === 0) {
        tbody.innerHTML = `
            <tr>
                <td colspan="8" class="px-6 py-12 text-center text-gray-500">
                    <i class="fas fa-inbox text-2xl mb-2"></i>
                    <p>暂无日志</p>
                </td>
            </tr>
        `;
        return;
    }
    
    tbody.innerHTML = logs.map(log => `
        <tr class="hover:bg-gray-50">
            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">${formatDateTime(log.created_at)}</td>
            <td class="px-6 py-4 whitespace-nowrap">
                <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${getMethodColor(log.method)}">
                    ${log.method}
                </span>
            </td>
            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-800 max-w-xs truncate" title="${log.endpoint}">
                ${log.endpoint}
            </td>
            <td class="px-6 py-4 whitespace-nowrap">
                <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${getStatusColor(log.status_code)}">
                    ${log.status_code}
                </span>
            </td>
            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-800">${(log.response_time * 1000).toFixed(0)}ms</td>
            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-800">${log.user_id || '-'}</td>
            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">${log.ip_address}</td>
            <td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
                <button onclick="viewLogDetails(${log.id})" class="text-blue-600 hover:text-blue-900">
                    <i class="fas fa-eye"></i>
                </button>
            </td>
        </tr>
    `).join('');
}

// 更新分页
function updatePagination() {
    const totalPages = Math.ceil(totalLogs / pageSize);
    const startItem = (currentPage - 1) * pageSize + 1;
    const endItem = Math.min(currentPage * pageSize, totalLogs);
    
    document.getElementById('startItem').textContent = startItem;
    document.getElementById('endItem').textContent = endItem;
    document.getElementById('totalItems').textContent = totalLogs;
    
    // 生成分页按钮
    const pagination = document.getElementById('pagination');
    let paginationHTML = '';
    
    // 上一页按钮
    paginationHTML += `
        <button onclick="changePage(${currentPage - 1})" ${currentPage === 1 ? 'disabled' : ''} 
                class="relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50 ${currentPage === 1 ? 'cursor-not-allowed' : ''}">
            <i class="fas fa-chevron-left"></i>
        </button>
    `;
    
    // 页码按钮
    for (let i = 1; i <= totalPages; i++) {
        if (i === 1 || i === totalPages || (i >= currentPage - 2 && i <= currentPage + 2)) {
            paginationHTML += `
                <button onclick="changePage(${i})" class="relative inline-flex items-center px-4 py-2 border text-sm font-medium ${
                    i === currentPage 
                        ? 'z-10 bg-blue-50 border-blue-500 text-blue-600' 
                        : 'bg-white border-gray-300 text-gray-500 hover:bg-gray-50'
                }">
                    ${i}
                </button>
            `;
        } else if (i === currentPage - 3 || i === currentPage + 3) {
            paginationHTML += `
                <span class="relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-700">
                    ...
                </span>
            `;
        }
    }
    
    // 下一页按钮
    paginationHTML += `
        <button onclick="changePage(${currentPage + 1})" ${currentPage === totalPages ? 'disabled' : ''} 
                class="relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50 ${currentPage === totalPages ? 'cursor-not-allowed' : ''}">
            <i class="fas fa-chevron-right"></i>
        </button>
    `;
    
    pagination.innerHTML = paginationHTML;
}

// 切换页面
function changePage(page) {
    const totalPages = Math.ceil(totalLogs / pageSize);
    if (page >= 1 && page <= totalPages) {
        currentPage = page;
        loadLogs();
        loadLogStats();
    }
}

// 查看日志详情
async function viewLogDetails(logId) {
    try {
        const log = await apiRequest(`/api/v1/admin/logs/${logId}`);
        const modal = document.getElementById('logModal');
        const details = document.getElementById('logDetails');
        
        details.innerHTML = `
            <div class="grid grid-cols-2 gap-4">
                <div>
                    <label class="block text-sm font-medium text-gray-700">ID</label>
                    <p class="text-sm text-gray-800">${log.id}</p>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">时间</label>
                    <p class="text-sm text-gray-800">${formatDateTime(log.created_at)}</p>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">方法</label>
                    <p class="text-sm text-gray-800">${log.method}</p>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">路径</label>
                    <p class="text-sm text-gray-800">${log.endpoint}</p>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">状态码</label>
                    <p class="text-sm text-gray-800">${log.status_code}</p>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">响应时间</label>
                    <p class="text-sm text-gray-800">${(log.response_time * 1000).toFixed(0)}ms</p>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">用户</label>
                    <p class="text-sm text-gray-800">${log.user_id || '-'}</p>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">客户端IP</label>
                    <p class="text-sm text-gray-800">${log.ip_address}</p>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">用户代理</label>
                    <p class="text-sm text-gray-800 text-xs">${log.user_agent || '-'}</p>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">请求参数</label>
                    <p class="text-sm text-gray-800 text-xs">${log.query_params || '-'}</p>
                </div>
            </div>
            
            ${log.request_body ? `
            <div class="mt-4 pt-4 border-t">
                <label class="block text-sm font-medium text-gray-700 mb-2">请求体</label>
                <div class="bg-gray-50 p-4 rounded-md max-h-48 overflow-y-auto">
                    <pre class="whitespace-pre-wrap text-sm text-gray-800">${log.request_body}</pre>
                </div>
            </div>
            ` : ''}
            
            ${log.response_body ? `
            <div class="mt-4 pt-4 border-t">
                <label class="block text-sm font-medium text-gray-700 mb-2">响应体</label>
                <div class="bg-gray-50 p-4 rounded-md max-h-48 overflow-y-auto">
                    <pre class="whitespace-pre-wrap text-sm text-gray-800">${log.response_body}</pre>
                </div>
            </div>
            ` : ''}
            
            ${log.error_message ? `
            <div class="mt-4 pt-4 border-t">
                <label class="block text-sm font-medium text-gray-700 mb-2">错误信息</label>
                <div class="bg-red-50 p-4 rounded-md">
                    <pre class="whitespace-pre-wrap text-sm text-red-800">${log.error_message}</pre>
                </div>
            </div>
            ` : ''}
        `;
        
        modal.classList.remove('hidden');
    } catch (error) {
        console.error('获取日志详情失败:', error);
        showNotification('获取日志详情失败', 'error');
    }
}

// 关闭日志详情模态框
function closeLogModal() {
    document.getElementById('logModal').classList.add('hidden');
}

// 导出日志
async function exportLogs() {
    try {
        const startDate = document.getElementById('startDate').value;
        const endDate = document.getElementById('endDate').value;
        const method = document.getElementById('methodFilter').value;
        const status = document.getElementById('statusFilter').value;
        const search = document.getElementById('searchInput').value;
        
        let url = '/api/v1/admin/logs/export';
        const params = new URLSearchParams();
        if (startDate) params.append('start_date', startDate);
        if (endDate) params.append('end_date', endDate);
        if (method) params.append('method', method);
        if (status) params.append('status', status);
        if (search) params.append('search', search);
        if (params.toString()) url += '?' + params.toString();
        
        const token = new URLSearchParams(window.location.search).get('token');
        const response = await fetch(url, {
            headers: {
                'Authorization': `Bearer ${token}`
            }
        });
        
        if (response.ok) {
            const blob = await response.blob();
            const downloadUrl = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = downloadUrl;
            a.download = `api_logs_${new Date().toISOString().split('T')[0]}.csv`;
            document.body.appendChild(a);
            a.click();
            window.URL.revokeObjectURL(downloadUrl);
            document.body.removeChild(a);
            showNotification('日志导出成功', 'success');
        } else {
            showNotification('日志导出失败', 'error');
        }
    } catch (error) {
        console.error('导出日志失败:', error);
        showNotification('导出日志失败', 'error');
    }
}

// 工具函数
function getMethodColor(method) {
    const colors = {
        'GET': 'bg-green-100 text-green-800',
        'POST': 'bg-blue-100 text-blue-800',
        'PUT': 'bg-yellow-100 text-yellow-800',
        'DELETE': 'bg-red-100 text-red-800'
    };
    return colors[method] || 'bg-gray-100 text-gray-800';
}

function getStatusColor(status) {
    if (status >= 200 && status < 300) {
        return 'bg-green-100 text-green-800';
    } else if (status >= 400 && status < 500) {
        return 'bg-yellow-100 text-yellow-800';
    } else if (status >= 500) {
        return 'bg-red-100 text-red-800';
    } else {
        return 'bg-gray-100 text-gray-800';
    }
}

function formatDateTime(dateString) {
    const date = new Date(dateString);
    return date.toLocaleString('zh-CN');
}
</script>
{% endblock %}